<!-- 第一天----------------

 1. 将登录页面的第一个输入框所关联的字段全部 更改 mobile
 2. 完善了登录表单的校验规则
 3. 为登录按钮绑定了点击事件和对应的处理函数
    3.1 做表单的预校验 表单组件上的方法validate
    3.2 测试登录的请求
 4. 跨域-配置反向代理服务  vue.config.js文件中devServe.proxy
 5. 最终是环境变量文件中设置 VUE_APP_BASE_API = '/api'
 6. 封装登录的接口 api/user.js
 7. 优化-将登录的请求的操作定义到store/modules/user.js模块中的action里


 8. token的存储
    vuex  本地  定义对应mutation和state中数据 保证token存储
 9. 消息提示 在user模块中登录的action里返回登录的响应数据 在login组件中await接收响应的数据 判断success字段做消息提示
 10. success为true  跳转首页  

 11. 优化  在拦截器中统一处理消息提示 需要单独导入Message组件
     拦截器的代码复制过来不要删, 修改将拦截器挂载给axios实例
 12. 登录失败抛出错误的promise
 13. try catch处理按钮的禁用状态

 https://vue3js.cn/  组件库和项目
 https://vue3js.cn/interview/  面试题
-->
<!-- 第二天----------------
 1. 登录拦截(页面拦截) 路由导航守卫(路由钩子) permission.js中
 2. 进度条插件nprogress  前置守卫开启nprogress.start()  后置守卫中结束 nprogress.done()
   正常的路由切换会经过前置和后置守卫,但是被强制拦截的是不会经过后置守卫的,需要单独nprogress.done()
 3. styles/sidebar.scss中处理左侧菜单的样式 和 左侧菜单的logo (有能力的同学看一下点击汉堡按钮如何实现折叠和收起) 
 4. navbar组件样式

 下午 个人信息渲染
 5. 准备获取个人基本信息的接口(api/user.js), 配置请求头headers携带token,在navbar组件中测试了一下接口
 6. 优化 在请求拦截器中headers中统一挂载了token
 7. 将个人信息存储到vuex中
    在store/modules/user.js 定义了action+mutation+state中userInfo  navBar组件触发对应的action
 8. 挂载了全局getter name 渲染用户名称   
 9. 先获取个人信息, 再放行进入到系统首页
   将navbar获取个人信息的操作 挪到 permission文件中 导航守卫的位置中
 10. 优化 频繁切换页面 频繁获取个人信息  
 11. 准备获取带头像的接口(api/user.js), 在store/modules/user.js 获取个人信息的action 再次发送第二次请求
 获取带头像的用户信息 将两个响应的结果 合并成一个新对象 存储到vuex
 12. 定义全局的 avatar getter 渲染 
 13. 碎图处理
   main.js 定义全局的自定义指令  带值  本地图片模块加载
 -->
<!-- 第三天----------------
1. 优化-抽离了自定义指令模块  src/directives/index.js 
  1.1 直接导入并注册所有指令
  1.2 按需导出  按需注册指令
  1.3 import * as 别名  配合for in 批量注册所有指令  
2. 退出功能
   2.1 绑定点击事件 .native
   2.2 确认消息框提示
   2.3 清除vuex+cookie中token  单独在store/modules/user.js  定义mutation 
   2.4 跳转到登录页面

3.token过期失效处理 401的错误
  在utils/request.js 响应拦截器的第二个处理函数中判断 响应状态码是否是401 响应的data.code === 10002
  清除vuex+cookie中token  跳转到登录页面
4. 左侧导航路由
   1. 清除了无效的路由规则和路由对应的组件
   2. views文件夹下新建好对应路由的组件页面
   3. 分析测试如何在这个项目中配置路由规则
   4. 复制首页的路由规则 测试组织架构的路由规则
   5. 新建了router/modules/xx.js 各自的路由规则 改路径 title icon
   6. 将各自的路由规则导入到 router/index.js  拆分静态路由数组和动态路由数组 合并展示到路由规则中
   7. 高亮效果
5. 组织架构页面
  1. 左右布局 card row col dropdown组件
  2. 树形控件 data props default-expand-all
-->
<!-- 第四天----------------
1. 为树形组件使用作用域插槽定制结构  data 每一行叶子的数据对象
2. 单独抽离了 treetools组件 (做左右布局的) 挂载到父组件上
3. 使用父传子将每一行的数据传递给treetools (需要单独为第一个treetools自定义一个对象)
4. 控制编辑和删除按钮的按需显示
5. 封装获取部门列表的接口 api/department.js 在组件中获取部门列表
6. 分析梳理部门与部门的关系 一级部门的pid是 ''  二级部门的pid是一级部门的id 
7. 使用递归函数实现部门列表数据的处理 
     debugger 将vue.config.js 反向代理地址 http://192.168.19.72:3000
8. 抽离处理部门列表数据的处理函数 到 utils/index
9. 样式处理 间距  对齐方式  图标.....(鸡肋) 
10. 为三个按钮绑定事件 command方式  @click.native
11. 对话框的展示与隐藏
    1. 新建了addDepts子组件, 放置的是对话框的结构  删除.sync
    2. 将addDepts子组件挂载到departments/index.vue中
    3. 将控制对话框展示的布尔值在departments/index.vue定义 showDialog
    4. 将父组件定义的showDialog布尔值传递给 addDepts子组件 props接收
    5. addDepts修改visible对应的属性值
    6.为treetools子组件中的添加按钮发布自定义事件 通知父组件将showDialog设置为true
    7.为addDepts组件中确定 取消 x按钮 绑定事件 子传父通知父组件将showDialog设置为false
12. 拦截器直接响应了 response.data 方便组件中页面中 获取数据少.一次data
-->
<!-- 第五天----------------
 1. 绘制了表单结构
 2. 定义表单关联的字段和基本的校验规则
 3. 单独为部门名称和部门编码定义自定义校验规则  validator: 处理函数  value cb()
 4. 获取了部门负责人列表 渲染部门负责人  manager 要的是负责人的名称
 5. 新增的第五个参数 pid
 5. 添加- 
     1. 为确定按钮绑定点击事件
     2. 表单的预校验
     3. 准备新增部门的接口发送新增的请求 5个参数
     4. 通知父组件关闭对话框 重新获取部门列表
 6.删除-
     1. 为删除按钮绑定点击事件
     2. 确认消息框提示
     3. 准备删除部门的接口发送删除的请求 id
     4. 通知父组件重新获取部门列表
 7.编辑-
   1. 通知父组件展示对话框
   2. 携带了点击的部门的id
   3. 在表单组件中定义获取部门详情的方法
   4. 在父组件中通过ref+$refs获取到子组件 并调用子组件获取部门的方法 
   5. 数据的回显
   6. 拆分了确定按钮的业务  form.id 
   7. 封装编辑提交的接口 发送编辑的请求   
   8. 通知父组件关闭对话框 重新获取部门列表 
   9. bug先编辑再新增的bug  form.id
-->
<!-- 第六天---------------- 
  1. 组织架构页面处理 编辑状态下的部门名称和部门编码校验规则  在编辑状态下 form.id+当前输入框的value值和编辑的部门信息比较 nodeData
  2. 处理了对话框的title标题
  3. 设置了整页面的loading 请求拦截器+响应拦截器中 
  4. tabs组件
  5. 表格组件
  6. 获取角色列表渲染表格数据
  7. 分页组件pagination
  8. 删除角色 核心是通过表格列的作用域插槽 拿到当前行id
  9. 删除角色表格数据只剩一行的bug page--
  10. 新增:
    1. 准备对话框组件 定义对应关联的布尔值
    2. 点击新增按钮将布尔值设置为true 点击对话框的确定/取消/x 设置布尔值为false
    3. 准备表单元素 表单数据关联(接口文档 注意描述是description) 表单校验规则
    4. 为确定按钮绑定点击事件 表单的预校验, 预校验(validate)通过后 (准备新增角色的接口)携带发送新增角色的请求
    5. 新增完成后 关闭对话框 重置表单和规则(resetFields())  重新渲染
  11. 编辑: 
    1. 点击编辑按钮展示对话框将布尔值设置为true
    2. 准备查询角色详情的接口获取数据 回显到表单中
    3. 拆分确定按钮的业务逻辑 form.id
    4. 准备编辑提交的接口 携带参数发送请求  关闭对话框 重置表单和规则(resetFields())  重新渲染
    
  12. 自定义索引列  type="index" :index="indexMethod"  
  13. 渲染公司信息







-->
<!-- 第七天----------------
 1. 封装通用的组件 src/components/PageTools  卡片左右布局  $slots
 2. Vue.use做了什么? vue的插件机制?
    Vue.use内部执行了一个install函数, install函数会接收Vue,
    导出的是一个对象 需要单独提供install方法 
    导出的是一个函数 这个函数会被当做install方法
 3. 员工页面的表格数据展示
    1.表格结构的绘制
    2.发送请求获取表格数据 prop属性展示对应的字段
    3.分页组件
    4.自定义索引列
    5.删除功能
4.聘用形式列的展示
  1. 作用域插槽处理
  2. formatter格式化列内容 配合常量数据

5.新增员工
  1. 展示对话框
  2. 表单结构的绘制和数据的定义和规则的定义
  3. 聘用形式的数据展示(常量数据)
  4. 部门
    4.1 输入框绑定点击事件.native 发送请求获取部门列表
    4.2 使用树形组件展示数据
    4.3 点击一次展示,再次点击隐藏 isShow
    4.4 为树形组件绑定node-click事件 完成部门的选中(选中没有子部门的部门)
    4.5 禁止输入  disabled readonly :value
    4.6 阻止事件冒泡  为对话框绑定点击事件 将isShow 设置布尔值为false
    4.7 样式处理  
-->
<!-- 第八天----------------
  1. 新增员工功能
    1.1 绑定点击事件
    1.2 预校验
    1.3 准备接口发送新增的请求
    1.4 关闭对话框重置表单
    1.5 重新渲染
  2. excel上传
   2.1 集成项目中找到导入excel的源码拉到项目中测试
   2.2.如何实现excel上传功能?
    2.2.1. 结构 点击按钮上传涉及到type="file" 文件域因为本身的文件域样式是不能修改的, 准备了ui界面相对好看的按钮
      点击了这个按钮触发文件与的点击事件, 相当于点击了文件域, 此时就可以选择文件上传了
    2.2.2. 通过给file文件与绑定change事件 获取上传的文件对象 e.target.files[0] ===>  坑????上传完文件后,将file的value值清空, 解决file文件域多次选择同样的文件不触发change事件的bug
    2.2.3. 做文件大小的限制+文件类型的限制? 借助xlsx包读取上传的excel文件的数据(表头+表体)
    2.2.4.（扩展）额外工作 拖拽上传 配合 dragenter+dragover+drop事件实现拖拽, 但是这三个方法有兼容性问题, 需要
  阻止事件冒泡和阻止默认行为,  e.dataTransfer.files[0]获取上传文件上传对象
  2.3
    1.准备上传import新的组件和新的路由规则
    2.改造了左右布局结构+样式
    3.准备接口拿着results上传处理  => 有问题  中文字段
    4.数据 => 汉译英
    5.携带处理完的数据发送批量导入的请求
    6.回到员工页面
    7.优化导入  添加query标识
  3.excel导出  
   3.1 集成项目中找到导出excel的源码拉到项目中测试
   3.2 简单表格的导出

-->
<!-- 第九天----------------
  excel导出
   1. 先获取了所有的员工列表
   2. 定义处理函数=>得到表格数据的二维数组
   3. 处理聘用形式列和日期列
   4. 多表头(了解)
  员工详情页面
  1. 点击查看按钮跳转到 /employees/detail/id   路由动态参数
  2. 新建对应详情组件和路由规则
  3. tabs标签页组件
  4. 面板一更新密码
    4.1 拿着路由参数的id获取用户的信息, 展示
    4.2 更新密码 (对象属性重写覆盖) 
  5. 面板二个人详情组件+面板三岗位详情  cv  
上传组件
  1. 腾讯云cos 代管图片 会将代管图片的地址返回
  2. 注册 认证 新建存储桶 并且开启跨域
  3. 新建ImageUpload组件 基于element-ui upload组件二次封装 全局挂载
  4. 封装组件
    4.1 样式 list-type="picture-card"
    4.2 action=""
    4.3 file-list="[{url}]"
    4.4 预览 :on-preview="handlePreview"
    4.5 控制+上传组件显示与隐藏 动态控制父元素的类名
    4.6 limit + 文件列表的长度 判断条件 

    ++++++++++++++++++++++++++++++++++++++++++++++++++++
    4.7 on-remove = fn 移除图像 同步 fileList数组
    4.8 http-request = fn 覆盖默认上传的行为 拿到了上传文件对象
    4.9 on-change=fn同步 fileList数组
    4.10 before-upload 上传前对象文件类型和文件的大小进行校验 size type
    前端实现本地图像预览两种方式 
      URL.createObjectURL() 临时路径  创建路径的页面关闭 路径也随之失效
      fileReader()文件读取对象 base64格式字符串路径 将文件放大30%
    5. 创建腾讯云实例将图片存储到存储桶中
      1. yarn add cos-js-sdk-v5
      2. 创建一组秘钥   创建腾讯云实例
      3. 基于http-request对应的处理函数 实现上传操作
      4. 在对应onProgress处理函数中 处理对应上传文件的进度条 status="uploading" percent百分比 上传完毕后设置status="success" 
      5. 上传完成后的处理函数中处理腾讯云真是地址替换  改箭头函数
   6. 在user-info页面使用上传组件   回显 更新提交
   7. 在头像列中使用插槽展示了图片头像
   8. 点击头像展示二维码
     8.1 准备了对话框
     8.2 yarn add qrcode
     8.3 对话框中准备 canvas 标签
     8.4 点击展示对话框的处理函数中   $nextTick qrcode.toCanvas(dom, info)
-->
<!-- 第十一天--------------
  1. 员工详情的后两个面板中 准备两个打印按钮 跳转到打印页面 准备组件和路由规则
  2. 打印页面 准备了表格 准备打印按钮  安装 vue-print-nb 全局注册 在需要打印的元素上 id  按钮 绑定v-print="'#id名'"
  3. 为员工分配角色
   3.1 准备对话框组件 抽离了子组件
   3.2 open事件对应的处理函数中 获取所有的角色列表
   3.3 配合复选框组和复选框组件渲染所有角色列表
   3.4 勾选当前用户已有的角色 => 获取用户信息 roleIds 赋值给复选框组的v-model的数组
   3.5 选中后发送请求 分配角色
   3.6 以最快的速度拿到多个并发请求的结果,  布尔值
   4. 页面访问权和按钮操作权
     一套 增删改查
-->
<!-- 第十三天-------------- 
   1. 为角色分配权限
    1.1. 准备对话框展示和隐藏
    1.2 获取权限列表处理成树形数据并展示在tree组件中 show-checkbox  check-strictly
    1.3 展示当前要分配权限的角色已有的权限  携带当前角色的id发送请求perIds 树形组件setCheckedKeys([])
    14. 分配权限 获取选中的权限点 getCheckedKeys() 发送请求
  2. 权限处理(核心)
    2.1 在store/modules/user 将个人信息return 在导航守卫中获取个人信息的menus字段
    2.2 测试addRoutes方法  是将router/index.js  routes 中的asyncRoutes移除
    2.3 处理addRoutes的bug  next(to.fullPath)  * 
    2.4 修改每一个动态路由的name和权限点字段保持一致
    2.5 基于权限点menus 过滤出来 当前用户已有的权限  addRoutes添加
    2.6 使用vuex管理路由规则(数据)
    2.7 sidebar/index.vue 中 遍历的routes 访问vuex管理的路由的数据
    2.8 404页面的问题
    2.9 退出重置路由规则
  3. 按钮操作权   使用函数返回一个布尔值 控制按钮的启用和禁用
  4. mixin
  5. 首页个人信息渲染 + 日历组件
 -->
<!-- 第十四天--------------
  1. 日历组件 
   1.1 准备了两个下拉菜单 月份遍历出来12
   1.2 Array.from + new Array() 模拟得到 前五年 + 今年+后五年 年份数组中
   1.3 为两个下拉菜单绑定change事件,拿到的年份和月份 生成一个新的日期对象交给日历组件的v-model
   1.4 侦听日历组件的数据的变化, 反过来赋值两个下拉菜单的值
   1.5 休息日处理 - dateCell作用域插槽 样式
  2.  vue中使用echarts  钩子 mounted(){} 钩子函数   echarts/highcharts
  3. 全屏处理
      新建screenfull组件
      准备两个svg 切换显示
      配合screenfull@5.2.0   screenfull.toggle()
  4. 换肤  
    1. 新建子组件ThemePicker  gitee仓库/src/components/themePicker cv 
    2. 默认颜色  store/moudles/setting 提供新的state状态
    3. 让默认颜色立即生效  组件内 theme侦听器 立即侦听 https://unpkg.com/element-ui@2.4.7/lib/theme-chalk/index.css  
    4. 将修改的颜色同步到vuex中(供别的组件使用) 直接使用提供好的action+mutation
    5. 颜色持久化存储  utils/auth 新建关于颜色的三个存储的方法  在仓库中调用实现本地存储






-->





